import numpy as np
import math
import random
import xlwt
import logging


class Playground:   # 标准化操场
    Playground_center = 0
    radius       = 37.898
    total        = 409
    straight     = (total - 2 * math.pi * radius) / 4
    left_center  = [Playground_center - straight, 0]
    right_center = [Playground_center + straight, 0]

    def _getDistanceByPoint(self,Point1,Point2):
        return math.sqrt((Point1[0]-Point2[0])**2+(Point1[1]-Point2[1])**2)
    
    def _getDistanceToPlayground(self,Point):
        if Point[0] < self.left_center[0]:
            return self._getDistanceByPoint(self.left_center,Point) - self.radius
        if Point[0] > self.right_center[0]:
            return self._getDistanceByPoint(self.right_center,Point) -self.radius
        if Point[1] == 0:
            print("Warning : 该点纵坐标为0！")
        if Point[1] > 0:
            return Point[1] - self.radius
        if Point[1] < 0:
            return self.radius - Point[1]

    def _getPointByDistance(self,mileage,Distance):
        mileage = mileage % 409
        rightTopNode    = self.straight
        rightBottomNode = rightTopNode + (2 * math.pi * self.radius) / 2
        leftBottomNode  = rightBottomNode + 2 * self.straight
        leftTopNode     = leftBottomNode + (2 * math.pi * self.radius) / 2
        if (mileage >= 0 and mileage <= rightTopNode ):
            return (mileage, self.radius + Distance)
        if (mileage > rightTopNode and mileage < rightBottomNode):
            arc    = mileage - rightTopNode
            degree = (0 + math.pi / 2) - (arc /self.radius)
            Pointx = self.straight + (self.radius + Distance) * math.cos(degree)
            Pointy = (self.radius + Distance) * math.sin(degree)
            
            return (Pointx,Pointy)
        if (mileage > rightBottomNode and mileage < leftBottomNode):
            Pointx = self.straight - (mileage - rightBottomNode)
            Pointy = - Distance - self.radius
            return (Pointx, Pointy)
        if(mileage > leftBottomNode and mileage < leftTopNode):
            arc = mileage - leftBottomNode
            degree = (0 - math.pi / 2) + (arc /self.radius)
            Pointx = -self.straight - (self.radius + Distance) * math.cos(degree)
            Pointy = (self.radius + Distance) * math.sin(degree)
            return (Pointx, Pointy)
        
        if(mileage > leftTopNode and mileage <409):
            Pointx = -self.straight+mileage-leftTopNode
            Pointy = self.radius + Distance
            return(Pointx,Pointy)
        
        print("错误！")
        
class Control:

    avgSpeed=5
    ShiftlingStart=-5
    ShiftlingStop=5
    Shiftling =0.5
    totalMileage=2150

    def __init__(self,ShiftlingStart=-5,ShiftlingStop=5,Shiftling=0.5,avgSpeed=5):
        self.ShiftlingStart=ShiftlingStart
        self.ShiftlingStop=ShiftlingStop
        self.avgSpeed=avgSpeed
        self.Shiftling=Shiftling
        
    def SpeedControl(self,mileage):
        Speed=self.avgSpeed+0.7-((mileage/self.totalMileage)*1.4)
        if Speed <self.avgSpeed-0.7:
            Speed=self.avgSpeed-0.7
        Speed=random.uniform(Speed-0.7,Speed+0.7)
        return Speed
    
    def ShiftingControl(self,lastShiftling):
        right=min(self.ShiftlingStop,lastShiftling+(self.Shiftling/2))
        left = max(self.ShiftlingStart,lastShiftling-(self.Shiftling/2))
        #return random.uniform(lastShiftling-self.Shiftling,lastShiftling + self.Shiftling)
        return random.uniform(left,right)

class Points(Control):
    mileage=random.randint(-15,10)
    lastShiftling=0
    PointsList=[]
    PL=Playground()
    dx = 36.12432223
    dy = 120.4846537
    std_numeratorx = 0.000688225519274115      # 纬度标准化分子
    std_numeratory = 0.000878225519274115      # 经度标准化分子

    def _addPoint(self,Point):
        self.PointsList.append(Point)

    def _getNextPoint(self):
        self.mileage = self.mileage + self.SpeedControl(self.mileage)
        self.lastShiftling = self.ShiftingControl(self.lastShiftling)
        oriPoint=self.PL._getPointByDistance(mileage=self.mileage,Distance=self.lastShiftling)
        StandardizationPoint=self._getStandardizationPoint(oriPoint)
        RenormalizationPoint=self._getRenormalizationPoint(StandardizationPoint)
        self._addPoint(Point=RenormalizationPoint)
    def _getStandardizationPoint(self,Point):
        return (- Point[0]/(self.PL.radius*2 + self.ShiftlingStop),- Point[1]/(self.PL.radius*2 + self.ShiftlingStop))
    
    def _getRenormalizationPoint(self,Point):
        Pointx=self.dx + Point[0] * self.std_numeratorx
        Pointy=self.dy + Point[1] * self.std_numeratory
        return (Pointx,Pointy)


class Nanjubeizhi(Points):
    def __init__(self,ShiftlingStart=-0.9,ShiftlingStop=0.9,Shiftling=1.0,avgSpeed=5,mileage=2150):
        self.avgSpeed=avgSpeed
        self.ShiftlingStart=ShiftlingStart
        self.ShiftlingStop=ShiftlingStop
        self.Shiftling=Shiftling
        self.totalMileage=mileage

    
    def getPointList(self):
        self.PointsList = []
        while(True):
            self._getNextPoint()
            if self.mileage >= self.totalMileage:
                break
        return self.PointsList
        
# a = Nanjubeizhi()

# workbook = xlwt.Workbook(encoding='utf-8')
# worksheet = workbook.add_sheet("test_sheet")
# worksheet.write(0, 0, label='x')
# worksheet.write(0, 1, label='y')
# for i, data in enumerate(a.getPointList()):
#     worksheet.write(i + 1, 0, label=data[0])
#     worksheet.write(i + 1, 1, label=data[1])
# workbook.save("xlwt_test.xls")